package com.tchepannou.limbe.gae.service;

import com.google.appengine.api.datastore.*;
import com.tchepannou.limbe.ServiceContext;
import com.tchepannou.limbe.dao.Dao;
import com.tchepannou.limbe.dao.DaoFactory;
import com.tchepannou.limbe.gae.converter.*;
import com.tchepannou.limbe.model.Model;
import com.tchepannou.limbe.service.PersistenceService;
import com.tchepannou.limbe.service.impl.AbstractService;
import com.tchepannou.util.converter.DefaultConverterFactory;

import java.io.Serializable;
import java.util.List;

/**
 * Implementation of {@link PersistenceService} based on GAE Datastore
 */
public class GaePersistenceService
        extends AbstractService
        implements PersistenceService
    {
        //-- Service overrides
        @Override
        public void init (ServiceContext sc)
        {
            super.init(sc);

            DefaultConverterFactory cf = DefaultConverterFactory.getInstance();
            cf.register(String.class, new StringConverterExt());
            cf.register(Text.class, new TextConverter());
            cf.register(Email.class, new EmailConverter());
            cf.register(Link.class, new LinkConverter());
        }

        //-- PersistenceService overrides
        public void beginTransaction ()
        {
            TransactionOptions to = TransactionOptions.Builder.withXG(true);
            DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
            ds.beginTransaction (to);
        }

        public void commitTransaction ()
        {
            DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
            Transaction tx = ds.getCurrentTransaction ();
            if ( tx != null )
            {
                tx.commit ();
            }
        }

        public void rollbackTransaction ()
        {
            DatastoreService ds = DatastoreServiceFactory.getDatastoreService ();
            Transaction tx = ds.getCurrentTransaction ();
            if ( tx != null )
            {
                tx.rollback ();
            }
        }

        public <T extends Model> T get(Serializable id, Class<T> type)
        {
            Dao dao = DaoFactory.get(type);
            return (T)dao.findById(id);
        }}
